﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WLW_timer
{
    public partial class Form1 : Form
    {

        SynchronizationContext sync1 = null; // 定义线程助手 更新串口
        SynchronizationContext sync2 = null; // 定义线程助手 接收数据
        SynchronizationContext sync3= null;

        public Form1()
        {
            InitializeComponent();
            startThread();
            sync1 = SynchronizationContext.Current; // 线程助手 获取上下文
            sync2 = SynchronizationContext.Current; // 线程助手 获取上下文
            sync3 = SynchronizationContext.Current;

            button_定时开启.Enabled = false;
            textBox_定时时间.Enabled = false;
            button_定时时间.Enabled = false;
        }

        Thread th1 = null; // 定义一个线程  用来更新串口
        Thread th2 = null;

        int startus = 0; // 线程标志位 控制发送       启动 暂停 恢复 退出 
        byte[] HEX_send = new byte[4] { 0x55, 0x00, 0x00, 0x66 };
        int HEX_Timer = -1;


        void updateText(object obj) // 线程助手 
        {
            string[] str = SerialPort.GetPortNames();

            for (int y = 0; y < str.Length; y++)
            {
                if (comboBox_串口号.Items.Contains(str[y]) == false)
                    comboBox_串口号.Items.Add(str[y]);
            }

            for (int y = 0; y < comboBox_串口号.Items.Count; y++)
            {
                if (str.Contains(comboBox_串口号.Items[y]) == false)
                {
                    if (button_打开串口.Text == "关闭")
                        serialPort_Clear(serialPort_串口);
                    comboBox_串口号.Items.Remove(comboBox_串口号.Items[y]);
                }
            }
        }

        void startThread() // 线程启动函数
        {
            if (startus != 0)  // 当 startus 为0时才能启动线程
                return;

            th1 = new Thread(myTast);
            th1.Start();
            startus = 1;
        }

        void myTast() // 线程函数
        {
            while (true)
            {
                Thread.Sleep(100);
                sync1.Post(updateText, null);
            }
        }

        void start_send_Thread()
        {
            th2 = new Thread(Read_Data);
            th2.Start();
        }

        void serialPort_Open(SerialPort obj)
        {
            try
            {
                obj.PortName = comboBox_串口号.Text;
                obj.Open();
                start_send_Thread();
                button_打开串口.Text = "关闭";
                label_变化灯.ForeColor = Color.Red;
                textBox_定时时间.Enabled = true;
                button_定时时间.Enabled = true;
                HEX_Timer_Send();
            }
            catch (Exception)
            {
                MessageBox.Show("串口被占用,或不存在");
            }
        }

        void serialPort_Clear(SerialPort obj)
        {
            obj.Close();
            button_打开串口.Text = "打开";
            label_变化灯.ForeColor = Color.Black;
            textBox_定时时间.Enabled = false;
            button_定时时间.Enabled = false;
            button_定时开启.Enabled = false;
        }

        void Read_Data()
        {
            while (true)
            {
                if (serialPort_串口.IsOpen)
                {
                    int data_size = serialPort_串口.BytesToRead;
                    if (data_size != 0)
                    {
                        byte[] recvBuf = new byte[data_size];
                        serialPort_串口.Read(recvBuf, 0, data_size); // 读取串口缓存中的数据
                        sync3.Post(HEX_Agreement, recvBuf);
                    }
                }
                Thread.Sleep(100);
            }
        }

        void HEX_Agreement(object obj)
        {
            HEX_Judge((byte[])obj);
        }

        void HEX_Start_Send()
        {
            HEX_send[1] = 0x01;
            if (button_定时开启.Text == "定时关闭")
            {
                HEX_send[2] = 0x00;
            }
            else if (button_定时开启.Text == "定时开启")
            {
                HEX_send[2] = 0x01;
            }
            serialPort_串口.Write(HEX_send, 0, HEX_send.Length);
        }

        void HEX_Timer_Send()
        {
            HEX_send[1] = 0x02;
            HEX_send[2] = byte.Parse(textBox_定时时间.Text);

            serialPort_串口.Write(HEX_send, 0, HEX_send.Length);
        }

        void HEX_Judge(byte[] recvBuf)
        {
            if (recvBuf.Length == 4)
            {
                if (recvBuf[0] == 0x55 && recvBuf[3] == 0x66)
                {
                    if (recvBuf[1] == 0x11)
                    {
                        label_定时时间.Text = recvBuf[2].ToString();
                    }
                    else if (recvBuf[1] == 0x12)
                    {
                        if (recvBuf[2] == 0x01)
                        {
                            label_定时开启.ForeColor = Color.Red;
                            button_定时开启.Text = "定时关闭";
                            button_定时开启.ForeColor = Color.Red;
                        }
                        else if (recvBuf[2] == 0x00)
                        {
                            label_定时开启.ForeColor = Color.Black;
                            button_定时开启.Text = "定时开启";
                            button_定时开启.ForeColor = Color.Black;
                        }
                    }
                    else if (recvBuf[1] == 0x13)
                    {
                        label_电压.Text = recvBuf[2].ToString();
                    }
                }
            }
        }

        private void button_打开串口_Click(object sender, EventArgs e)
        {
            if (button_打开串口.Text == "打开")
            {
                serialPort_Open(serialPort_串口);
            }
            else
            {
                serialPort_Clear(serialPort_串口);
            }
        }

        private void button_定时开启_Click(object sender, EventArgs e)
        {
            if(serialPort_串口.IsOpen)
                HEX_Start_Send();
        }

        private void button_定时时间_Click(object sender, EventArgs e)
        {
            if (serialPort_串口.IsOpen && textBox_定时时间.Text != "")
            {
                if (HEX_Timer != int.Parse(textBox_定时时间.Text) && textBox_定时时间.Text != "0")
                {
                    HEX_Timer_Send();
                    HEX_Timer = int.Parse(textBox_定时时间.Text);
                    button_定时开启.Enabled = true;
                }
            }
        }

        private void button_退出_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void label_定时时间_Click(object sender, EventArgs e)
        {

        }

        private void textBox_定时时间_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
                e.Handled = true;
        }

        private void textBox_定时时间_TextChanged(object sender, EventArgs e)
        {
            if (textBox_定时时间.Text != "")
            {
                int number = int.Parse(textBox_定时时间.Text);
                textBox_定时时间.Text = number.ToString();
                if (number <= 255)
                {
                    return;
                }
                textBox_定时时间.Text = "255";
            }
        }
    }
}
